﻿#include <QTextCodec>
#include <QtNetwork>
#include "serverthread.h"
//#include "des.h"

serverthread::serverthread(QTcpSocket *parent,QString ip,quint16 port):QTcpSocket(parent)
{
    m_ip = ip;
    m_port = port;
    m_heartTimes = 0;

    preCmd = CmdType::Other;

    m_pConnect = new QTimer(this);
    m_pConnect->setSingleShot(true);
    connect(m_pConnect,SIGNAL(timeout()),this,SLOT(connectTimeout()));

    m_pHeart = new QTimer(this);
    connect(m_pHeart,SIGNAL(timeout()),this,SLOT(heartTimeout()));
    //started();
}

bool serverthread::saveToDisk(const QString &filename, const QByteArray data)
{
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly)) {
        fprintf(stderr, "Could not open %s for writing: %s\n",
                qPrintable(filename),
                qPrintable(file.errorString()));
        return false;
    }

    file.write(data.data(),data.size());
    file.close();

    return true;
}

void serverthread::Write(const QByteArray &data){
    qDebug()<<data;
    write(data);
}

void serverthread::ireadyRead(){
    m_getData.append(readAll());
    int index = m_getData.indexOf('\n');
    QByteArray line;
    cc1:
    if(-1 == index){
        return;
    }
    line = m_getData.left(index);
    m_getData = m_getData.remove(0,index+1);//m_getData.right(m_getData.length()-index-1);//.remove(0,line+1);
//    qDebug()<<line;
    if(!line.startsWith("@@")){
        qWarning()<<"Error Start";
        return;
    }
    if(line.mid(2,4).toInt()!=line.size()){
        qWarning()<<"Error data length";
        return;
    }
    int type=line.mid(6,4).toInt();
    int answer = 1;
    if(type==CmdType::HeartBeat){
        m_heartTimes=0;
//        qDebug()<<line;
        goto cc2;
    }
    if(type==CmdType::Register){
//        qDebug()<<"Register:"<<line;
        if(QString::fromUtf8(line.right(line.size()-10)).startsWith("success",Qt::CaseInsensitive))
            answer = 0;//emit MessageRev(0,0,QString::fromUtf8(line.right(line.size()-10)));
        else
            answer = 1;
    }
    else if(type==CmdType::NewUser){//new user
//        QString send = "Registed Success|"+QString::fromUtf8(line).split(":").value(1);
//        emit MessageRev(1,preCmd,send);
        answer = 0;
    }
    else if(type==CmdType::AddNewUser){//add user

        answer = 0;
    }
    else if(type==CmdType::RemoveUser){
        answer = 0;
    }
    else if(type==CmdType::NewMessageReturn){
        answer = 0;
    }
    else if(type==CmdType::NewMessage){
        answer = 0;
    }
    else if(type==CmdType::ConfigSetReturn){
        answer = 0;
    }
    else if(type==CmdType::ConfigSet){
        answer = 0;
    }
    else if(type==CmdType::NewMessageFileReturn){
        answer = 0;
    }
    else if(type==CmdType::NewMessageFile){
        answer = 0;
    }
    else if(type==CmdType::NewMessageFileGroup){
        answer = 0;
    }
    else if(type==CmdType::GetPiIP){
        answer = 0;
    }
    else{
        qWarning()<<"read error code:"<<type;
        goto cc2;
    }
    emit MessageRev(answer,type,QString::fromUtf8(line.right(line.size()-10)));
    cc2:
    index = m_getData.indexOf('\n');
    goto cc1;
}

void serverthread::ierror(QAbstractSocket::SocketError SocketError){
    QString errorStr;
    switch (SocketError) {
    case QAbstractSocket::RemoteHostClosedError:
        errorStr = "The host was Closed. Please check.";
        break;
    case QAbstractSocket::HostNotFoundError:
        errorStr = "The host was not found. Please check.";
        break;
    case QAbstractSocket::ConnectionRefusedError:
        errorStr = "The connection was refused by the peer.";
        break;
    default:
        errorStr = QString("The following error occurred:%1.").arg(errorString());
        break;
    }
    qWarning()<<errorStr;
    emit SocketStateChange(state(),errorStr);
}

void serverthread::iconnected(){
    emit SocketStateChange(state(),tr("Connected"));
    m_heartTimes=0;
    m_pHeart->start(30000);
}

void serverthread::idisconnected(){
    qDebug()<<"disconnected";
    close();
    m_pHeart->stop();
    m_pConnect->start(3000);
    emit SocketStateChange(state(),tr("Disconnected"));
}

void serverthread::istateChanged(QAbstractSocket::SocketState state){
    qDebug()<<state;
}

void serverthread::connectTimeout(){
    connectToHost(m_ip,m_port);
    if(!waitForConnected(3000)){
        close();
        m_pConnect->start(10000);
    }
    else{
        m_pConnect->stop();
    }
}

void serverthread::heartTimeout()
{
    if(m_heartTimes){
        qDebug()<<"heart Timeout,close connecting";
        m_heartTimes=0;
        CloseTcp();
    }
    else{
        int type=0;
        QString value = "";
        QByteArray stv;
        stv.append(value.toUtf8());
        QString pagedata = QString("@@%1%2").arg(stv.size()+10,4,10,QLatin1Char('0')).arg(type,4,10,QLatin1Char('0'));
        stv.insert(0,pagedata.toUtf8());
        stv.append('\n');
        write(stv);
    }
    m_heartTimes++;
}

void serverthread::started(){
    connect(this,SIGNAL(readyRead()),this,SLOT(ireadyRead()));
    connect(this,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(ierror(QAbstractSocket::SocketError)));
    connect(this,SIGNAL(connected()),this,SLOT(iconnected()));
    connect(this,SIGNAL(disconnected()),this,SLOT(idisconnected()));
    connect(this,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(istateChanged(QAbstractSocket::SocketState)));
    ConnectTcp(m_ip,m_port);
}

void serverthread::ConnectTcp(QString ip,quint16 port){
    if(isOpen())
        close();
    if(m_pConnect->isActive())
        m_pConnect->stop();
    m_ip = ip;
    m_port = port;

    connectToHost(m_ip,m_port);
    if(!waitForConnected(3000)){
        close();
        m_pConnect->start(10000);
    }
    else{
        qDebug()<<"ConnectTcp success";
    }
}

void serverthread::CloseTcp(){
    close();
}
